<?php
namespace App\Http\Controllers\ApiQd;

use App\Service\ApiQd\WxPayService;
use Illuminate\Http\Request;

class WxPayController extends BaseController
{
    //微信支付

    //必须的参数
    protected $app_id = 'wxad7c7696f8810af0'; //小程序ID
    protected $mch_id = '1683618974'; //商户号
    protected $key = 'karcvn13a3mj1yfysww0dzcnbic4ec8r'; //秘钥
    protected $notify_url = ''; //通知接口
    protected $notify_url2 = ''; //通知接口

    public function __construct()
    {
        $this->notify_url = env('DOMAIN') . '/api/qd/pay/notice';
        $this->notify_url2 = env('DOMAIN') . '/api/qd/pay/notice2';
        $this->db = new WxPayService();
    }

    //测试下单
    public function testorder()
    {
        $xml = "<xml><return_code><![CDATA[SUCCESS]]></return_code>
                <return_msg><![CDATA[OK]]></return_msg>
                <result_code><![CDATA[SUCCESS]]></result_code>
                <mch_id><![CDATA[1683618974]]></mch_id>
                <appid><![CDATA[wx081bb28635ee4455]]></appid>
                <nonce_str><![CDATA[XCwl17pf3PAXRDlj]]></nonce_str>
                <sign><![CDATA[EEECC087738BEFEAAA443B0A9B64B04B]]></sign>
                <prepay_id><![CDATA[wx2808401300205778f79505023bc2c50001]]></prepay_id>
                <trade_type><![CDATA[JSAPI]]></trade_type>
                </xml>";
        $xml = $this->xml2arr($xml);
        return $this->toJson(0, '', $xml);
    }

    /**
     * 统一下单
     * https://api.mch.weixin.qq.com/pay/unifiedorder
     */
    public function wxorder(Request $request)
    {
        $token = $request->post('token', '');
        $uOne = $this->db->getOpenidByToken($token);
        if ($uOne['code'] < 0) {
            return $this->toJson(-2, $uOne['msg']);
        }
        $type = $request->post('type', 0); //1会员充值，2订单支付，3佣金支付
        $orderno = $request->post('id', 0); //会员级别ID，或者订单号
        $price = $request->post('price', 0);// 会员充值
        $price = $price*100;//转成分
        if (!in_array($type, [1, 2, 3])) {
            return $this->toJson(-2, '类型错误');
        }
        if($type == 3){
            if ($uOne['data']['commission_pay'] == 1) {
                return $this->toJson(-2, '您已支付佣金，无需重新支付');
            }
            //$commission_price = getConfig('bond');
//            if (!$commission_price){
//                return $this->toJson(-2, '保证金金额未设置');
//            }
//            $resConfig = $this->config('bond');
//            if ($resConfig['code'] < 0){
//                return $this->toJson(-2, '保证金金额未设置');
//            }
//            $orderOne['data'] = $resConfig['commission'];
            if (!$price) {
                return $this->toJson(-2, '保证金必须的');
            }
            $orderOne['data'] = $price;
            $orderOne['code'] = 0;
        }elseif ($type == 1){
            $orderOne['data'] = $price;
            $orderOne['code'] = 0;
        }
        else{
            $orderOne = $this->db->getOrderOne($type, $orderno);
        }
        if ($orderOne['code'] < 0) {
            return $this->toJson(-2, $orderOne['msg']);
        }
        $type_name = '';
        if ($type == 1) {
            $type_name = 'recharge';
            $orderno .= '_' . time();
        } elseif($type == 2) {
            $type_name = 'order';
        } elseif ($type == 3) {
            $type_name = 'commission';
            $orderno .= '_' . time();
        }
        $openid = $uOne['data']['openid'];
        $uid = $uOne['data']['id'];
        $nonce = toOrderno();
        $amount  = $orderOne['data'];
        $userIp = $this->getUserIp();
        //构建签名
        $signs = [
            'appid' => $this->app_id,
            'mch_id' => $this->mch_id,
            'nonce_str' => $nonce,
            'body' => $type_name,
            'notify_url' => $this->notify_url,
            'out_trade_no' => $orderno,
            'spbill_create_ip' => $userIp,
            'total_fee' => $amount,
            'trade_type' => 'JSAPI',
            'sign_type' => 'MD5',
            'openid' => $openid,
        ];
        ksort($signs);
        $string = '';
        foreach ($signs as $k => $v) {
            if ($v) {
                $string .= $k . '=' . $v . '&';
            }
        }
        $string .= 'key=' . $this->key;
        $payData = [
            'uid' => $uid,
            'type' => $type,
            'out_trade_no' => $orderno,
            'money' => $amount,
            'wx_order_sign' => $string,
        ];
        $lastid = $this->db->payAdd($payData); //支付log
        $signStr = strtoupper(md5($string));
        //构建请求参数
        $param = '';
        $param .= '<xml>';
        $param .= '<appid>' . $this->app_id . '</appid>';
        $param .= '<body>' . $type_name . '</body>';
        $param .= '<mch_id>' . $this->mch_id . '</mch_id>';
        $param .= '<nonce_str>' . $nonce . '</nonce_str>';
        $param .= '<notify_url>' . $this->notify_url . '</notify_url>';
        $param .= '<out_trade_no>' . $orderno . '</out_trade_no>';
        $param .= '<spbill_create_ip>' . $userIp . '</spbill_create_ip>';
        $param .= '<total_fee>' . $amount . '</total_fee>';
        $param .= '<trade_type>JSAPI</trade_type>';
        $param .= '<openid>' . $openid . '</openid>';
        $param .= '<sign_type>MD5</sign_type>';
        $param .= '<sign>' . $signStr . '</sign>';
        $param .= '</xml>';
        $this->db->payModify($lastid, ['wx_order_req'=>$param]);
        $httpUrl = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $res = $this->toCurl($httpUrl, $param);
        $payData = [
            'wx_order_back' => json_encode($res, JSON_UNESCAPED_UNICODE),
        ];
        $this->db->payModify($lastid, $payData); //支付log
        if ($res['code'] < 0) {
            return $this->toJson(-2, $res['msg']);
        }
        //用于唤起的参数
        $resData = [
            'appId' => $this->app_id,
            'timeStamp' => (string) time(),
            'nonceStr' => toOrderno(),
            'package' => 'prepay_id=' . $res['data']['prepay_id'],
            'signType' => 'MD5',
        ];
        ksort($resData);
        $string = '';
        foreach ($resData as $k => $v) {
            if ($v) {
                $string .= $k . '=' . $v . '&';
            }
        }
        $string .= 'key=' . $this->key;
        //var_dump($string); echo '<br/>';
        $resData['mchId'] = $this->mch_id;
        //$resData['orderInfo'] = 'order info (goods detail info)';
        $resData['orderInfo'] = $type_name;
        $resData['key'] = $this->key;
        $resData['paySign'] = strtoupper(md5($string));
        $payData = [
            'pay_info' => json_encode($resData, JSON_UNESCAPED_UNICODE),
            'status' => 1,
        ];
        $this->db->payModify($lastid, $payData); //支付log
        return $this->toJson(0, '', $resData);
    }

    /**
     * 构建CURL请求，单线程
     * @param string $httpUrl 请求地址
     * @param string $string 参数拼接的字符串
     * @return $json
     */
    public function toCurl($httpUrl = '', $string = '', $is_pem = 0)
    {
        $curl = curl_init(); //初始化
        curl_setopt($curl,CURLOPT_URL,$httpUrl);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_FORBID_REUSE, 1);
        curl_setopt($curl, CURLOPT_FRESH_CONNECT, 1);
        curl_setopt($curl, CURLOPT_ENCODING, '');
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $string);
        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json', 'Content-Length: ' . strlen($string)
        ));
        if ($is_pem) {
            curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');
            curl_setopt($curl, CURLOPT_SSLCERT, '/www/tiepi/public/apiclient_cert.pem');
            curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
            curl_setopt($curl, CURLOPT_SSLKEY, '/www/tiepi/public/apiclient_key.pem');
        }
        curl_setopt($curl, CURLOPT_TIMEOUT, 5);
        $output = curl_exec($curl);
        curl_close($curl);
        //ddd($output);
        if (!$output) {
            return array('code'=>-1, 'msg'=>'请求失败');
        }
        //$items = json_decode($output,true);
        if ($is_pem) {
            $items = $this->xml2arr2($output);
        } else {
            $items = $this->xml2arr($output);
        }
        if ($items['code'] < 0) {
            return array('code' => -2,'msg' => 'XML解析错误', 'data' => $items);
        }
        return array('code' => 0,'msg' => 'success', 'data' => $items['data']);
    }

    //解析xml
    public function xml2arr($xml)
    {
        $items = [];
        ////////////////////////正则匹配
        $prefix = '<![CDATA['; $suffix = ']]>';
        //return_code
        $res = preg_match('/<return_code>(.*?)<\/return_code>/', $xml, $matches);
        if (!$res) {
            return array('code' => -2, 'msg' => 'return_code 缺失', 'data' => $xml);
        }
        $return_code = $matches[1];
        if (substr($return_code, 0, strlen($prefix)) == $prefix) {
            $return_code = substr($return_code, 9);
        }
        if (substr($return_code, -3) == $suffix) {
            $return_code = substr($return_code, 0, -3);
        }
        $items['return_code'] = $return_code;
        //result_code
        $res = preg_match('/<result_code>(.*?)<\/result_code>/', $xml, $matches);
        if (!$res) {
            return array('code' => -2, 'msg' => 'result_code 缺失', 'data' => $xml);
        }
        $result_code = $matches[1];
        if (substr($result_code, 0, strlen($prefix)) == $prefix) {
            $result_code = substr($result_code, 9);
        }
        if (substr($result_code, -3) == $suffix) {
            $result_code = substr($result_code, 0, -3);
        }
        $items['result_code'] = $result_code;
        //prepay_id
        $res = preg_match('/<prepay_id>(.*?)<\/prepay_id>/', $xml, $matches);
        if (!$res) {
            return array('code' => -2, 'msg' => 'prepay_id 缺失', 'data' => $xml);
        }
        $prepay_id = $matches[1];
        if (substr($prepay_id, 0, strlen($prefix)) == $prefix) {
            $prepay_id = substr($prepay_id, 9);
        }
        if (substr($prepay_id, -3) == $suffix) {
            $prepay_id = substr($prepay_id, 0, -3);
        }
        $items['prepay_id'] = $prepay_id;
        //return_msg
        $res = preg_match('/<return_msg>(.*?)<\/return_msg>/', $xml, $matches);
        if (!$res) {
            return array('code' => -2, 'msg' => 'prepay_id 缺失', 'data' => $xml);
        }
        $return_msg = $matches[1];
        if (substr($return_msg, 0, strlen($prefix)) == $prefix) {
            $return_msg = substr($return_msg, 9);
        }
        if (substr($return_msg, -3) == $suffix) {
            $return_msg = substr($return_msg, 0, -3);
        }
        $items['return_msg'] = $return_msg;
        //判断错误
        if ($return_code != 'SUCCESS' || $result_code != 'SUCCESS') {
            return array('code' => -2, 'msg' => $return_msg, 'data' => $xml);
        }
//        ////////////////////////xml解析
//        $xml = simplexml_load_string($xml);
//        $items = json_decode(json_encode($xml), true);
//        ////////////////////////xml解析
//        $dom = new \DOMDocument();
//        $dom->loadXML($xml);  // 加载XML字符串
//        $root = $dom->documentElement;  // 获取根元素
//        foreach ($root->childNodes as $node) {  // 遍历子节点
//            if ($node->nodeType === XML_ELEMENT_NODE) {
//                $items[$node->nodeName] = $node->nodeValue;
//            }
//        }
//        ////////////////////////xml文件解析
//        $reader = new \XMLReader();
//        $reader->open($xml);  // 打开XML文件
//        while ($reader->read()) {  // 循环读取每个节点
//            if ($reader->nodeType === \XMLReader::ELEMENT) {
//                $name = $reader->name;
//                $reader->read();  // 读取节点值
//                $value = $reader->value;
//                $items[$name] = $value;
//            }
//        }
//        $reader->close();  // 关闭XMLReader
        ////////////////////////
        return array('code' => 0, 'msg' => 'success', 'data' => $items);
    }

    //解析xml退款
    public function xml2arr2($xml)
    {
        $items = [];
        ////////////////////////正则匹配
        $prefix = '<![CDATA['; $suffix = ']]>';
        //return_code
        $res = preg_match('/<return_code>(.*?)<\/return_code>/', $xml, $matches);
        if (!$res) {
            return array('code' => -2, 'msg' => 'return_code 缺失', 'data' => $xml);
        }
        $return_code = $matches[1];
        if (substr($return_code, 0, strlen($prefix)) == $prefix) {
            $return_code = substr($return_code, 9);
        }
        if (substr($return_code, -3) == $suffix) {
            $return_code = substr($return_code, 0, -3);
        }
        $items['return_code'] = $return_code;
        //result_code
        $res = preg_match('/<result_code>(.*?)<\/result_code>/', $xml, $matches);
        if (!$res) {
            return array('code' => -2, 'msg' => 'result_code 缺失', 'data' => $xml);
        }
        $result_code = $matches[1];
        if (substr($result_code, 0, strlen($prefix)) == $prefix) {
            $result_code = substr($result_code, 9);
        }
        if (substr($result_code, -3) == $suffix) {
            $result_code = substr($result_code, 0, -3);
        }
        $items['result_code'] = $result_code;
        //return_msg
        $res = preg_match('/<return_msg>(.*?)<\/return_msg>/', $xml, $matches);
        if (!$res) {
            return array('code' => -2, 'msg' => 'prepay_id 缺失', 'data' => $xml);
        }
        $return_msg = $matches[1];
        if (substr($return_msg, 0, strlen($prefix)) == $prefix) {
            $return_msg = substr($return_msg, 9);
        }
        if (substr($return_msg, -3) == $suffix) {
            $return_msg = substr($return_msg, 0, -3);
        }
        $items['return_msg'] = $return_msg;
        //判断错误
        if ($return_code != 'SUCCESS' || $result_code != 'SUCCESS') {
            return array('code' => -2, 'msg' => $return_msg, 'data' => $xml);
        }
        return array('code' => 0, 'msg' => 'success', 'data' => $items);
    }

    //微信通知
    public function notice()
    {
//        $this->db->addApiCount($request);
//        $wxdata = $request->all();
        $xml = file_get_contents('php://input');
//        $xml = '"<xml><appid><![CDATA[wx081bb28635ee4455]]><\/appid>\n<bank_type><![CDATA[OTHERS]]><\/bank_type>\n<cash_fee><![CDATA[1]]><\/cash_fee>\n<fee_type><![CDATA[CNY]]><\/fee_type>\n<is_subscribe><![CDATA[N]]><\/is_subscribe>\n<mch_id><![CDATA[1683618974]]><\/mch_id>\n<nonce_str><![CDATA[20240829160754372927]]><\/nonce_str>\n<openid><![CDATA[oyzUn7YniZJXR2S7LTPWT79jmjkw]]><\/openid>\n<out_trade_no><![CDATA[20240829160752940963]]><\/out_trade_no>\n<result_code><![CDATA[SUCCESS]]><\/result_code>\n<return_code><![CDATA[SUCCESS]]><\/return_code>\n<sign><![CDATA[A0C12B7857B7ECF29FF83AA0525B76F3]]><\/sign>\n<time_end><![CDATA[20240829160810]]><\/time_end>\n<total_fee>1<\/total_fee>\n<trade_type><![CDATA[JSAPI]]><\/trade_type>\n<transaction_id><![CDATA[4200002437202408293571189561]]><\/transaction_id>\n<\/xml>"';
//        $xml = '"<xml><appid><![CDATA[wx081bb28635ee4455]]><\/appid>\n<bank_type><![CDATA[OTHERS]]><\/bank_type>\n<cash_fee><![CDATA[1]]><\/cash_fee>\n<fee_type><![CDATA[CNY]]><\/fee_type>\n<is_subscribe><![CDATA[N]]><\/is_subscribe>\n<mch_id><![CDATA[1683618974]]><\/mch_id>\n<nonce_str><![CDATA[20240829160754372927]]><\/nonce_str>\n<openid><![CDATA[oyzUn7YniZJXR2S7LTPWT79jmjkw]]><\/openid>\n<out_trade_no><![CDATA[20240829160752940963]]><\/out_trade_no>\n<result_code><![CDATA[SUCCESS]]><\/result_code>\n<return_code><![CDATA[SUCCESS]]><\/return_code>\n<sign><![CDATA[A0C12B7857B7ECF29FF83AA0525B76F3]]><\/sign>\n<time_end><![CDATA[20240829160810]]><\/time_end>\n<total_fee>1<\/total_fee>\n<trade_type><![CDATA[JSAPI]]><\/trade_type>\n<transaction_id><![CDATA[4200002437202408293571189561]]><\/transaction_id>\n<\/xml>"';
//        $xml = json_decode($xml);
//        return $this->toJson(0, '', $xml);
//        $xml = '
//        <xml>
//          <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
//          <attach><![CDATA[支付测试]]></attach>
//          <bank_type><![CDATA[CFT]]></bank_type>
//          <fee_type><![CDATA[CNY]]></fee_type>
//          <is_subscribe><![CDATA[N]]></is_subscribe>
//          <mch_id><![CDATA[10000100]]></mch_id>
//          <nonce_str><![CDATA[5d2b6c2a8db53831f7eda20af46e531c]]></nonce_str>
//          <openid><![CDATA[oUpF8uMEb4qRXf22hE3X68TekukE]]></openid>
//          <out_trade_no><![CDATA[1409811653]]></out_trade_no>
//          <result_code><![CDATA[SUCCESS]]></result_code>
//          <return_code><![CDATA[SUCCESS]]></return_code>
//          <sign><![CDATA[B552ED6B279343CB493C5DD0D78AB241]]></sign>
//          <time_end><![CDATA[20140903131540]]></time_end>
//          <total_fee>1</total_fee>
//          <coupon_fee><![CDATA[10]]></coupon_fee>
//          <coupon_count><![CDATA[1]]></coupon_count>
//          <coupon_type><![CDATA[CASH]]></coupon_type>
//          <coupon_id><![CDATA[10000]]></coupon_id>
//          <trade_type><![CDATA[JSAPI]]></trade_type>
//          <transaction_id><![CDATA[1004400740201409030005092168]]></transaction_id>
//        </xml>
//        ';
        $lastid = $this->db->notice($xml);
        $prefix = '<![CDATA['; $suffix = ']]>';
        //return_code
        $res = preg_match('/<return_code>(.*?)<\/return_code>/', $xml, $matches);
        if (!$res) {
            return $this->toJson(-2, 'return_code 缺失');
        }
        $return_code = $matches[1];
        if (substr($return_code, 0, strlen($prefix)) == $prefix) {
            $return_code = substr($return_code, 9);
        }
        if (substr($return_code, -3) == $suffix) {
            $return_code = substr($return_code, 0, -3);
        }
        if ($return_code != 'SUCCESS') {
            return $this->toJson(-2, '通信失败');
        }
        $items['return_code'] = $return_code;
        //result_code
        $res = preg_match('/<result_code>(.*?)<\/result_code>/', $xml, $matches);
        if (!$res) {
            return $this->toJson(-2, 'result_code 缺失');
        }
        $result_code = $matches[1];
        if (substr($result_code, 0, strlen($prefix)) == $prefix) {
            $result_code = substr($result_code, 9);
        }
        if (substr($result_code, -3) == $suffix) {
            $result_code = substr($result_code, 0, -3);
        }
        if ($result_code != 'SUCCESS') {
            return $this->toJson(-2, '交易失败');
        }
        $items['result_code'] = $return_code;
        //out_trade_no
        $res = preg_match('/<out_trade_no>(.*?)<\/out_trade_no>/', $xml, $matches);
        if (!$res) {
            return $this->toJson(-2, 'out_trade_no 缺失');
        }
        $out_trade_no = $matches[1];
        if (substr($out_trade_no, 0, strlen($prefix)) == $prefix) {
            $out_trade_no = substr($out_trade_no, 9);
        }
        if (substr($out_trade_no, -3) == $suffix) {
            $out_trade_no = substr($out_trade_no, 0, -3);
        }
        $items['out_trade_no'] = $out_trade_no;
        $this->db->noticeModify($lastid, $out_trade_no);
        $this->db->setGsale($out_trade_no);
        return $this->toJson(0, '', $items);
    }

    //余额支付
    public function balance(Request $request)
    {
        $token = $request->post('token', '');
        $orderno = $request->post('orderno', '');
        $res = $this->db->payByBalance($token, $orderno);
        if ($res['code'] < 0) {
            return $this->toJson(-2, $res['msg']);
        }
        return $this->toJson();
    }

    //退款
    public function refund(Request $request)
    {
        $token = $request->post('token', '');
        $orderno = $request->post('orderno', '');
        $uid = $this->db->getUidByToken($token);
        if (!$uid) {
            return $this->toJson(-2, '没有登录');
        }
        $res = $this->db->refundOrderOne($orderno);
        if ($res['code'] < 0) {
            return $this->toJson(-2, $res['msg']);
        }
        $payWay = $res['data']['payWay'];
        $type = $res['data']['type'];
        $realPay = $res['data']['realPay'];
        if ($payWay == 2) {
            $res = $this->db->refundBalance($uid, $orderno, $realPay);
        } else {
            $res = $this->wxRefund($uid, $orderno, $realPay);
        }
        if ($res['code'] < 0) {
            return $this->toJson(-2, $res['msg']);
        }
        return $this->toJson();
    }

    //退款，提供后台调用
    public function refundByAuth($uid, $orderno)
    {
        $res = $this->db->refundOrderOne($orderno);
        if ($res['code'] < 0) {
            return $this->toJson(-2, $res['msg']);
        }
        $payWay = $res['data']['payWay'];
        $type = $res['data']['type'];
        $realPay = $res['data']['realPay'];
        if ($payWay == 2) {
            $res = $this->db->refundBalance($uid, $orderno, $realPay);
        } else {
            $res = $this->wxRefund($uid, $orderno, $realPay);
        }
        if ($res['code'] < 0) {
            return $this->toJson(-2, $res['msg']);
        }
        return $this->toJson();
    }

    //微信退款
    public function wxRefund($uid, $orderno, $amount)
    {
        //https://api.mch.weixin.qq.com/secapi/pay/refund
        $httpUrl = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
        $nonce = toOrderno();
        $out_refund_no = toOrderno();
        $signs = [
            'appid' => $this->app_id,
            'mch_id' => $this->mch_id,
            'nonce_str' => $nonce,
            'notify_url' => $this->notify_url2,
            'out_refund_no' => $out_refund_no,
            'out_trade_no' => $orderno,
            'total_fee' => $amount,
            'refund_fee' => $amount,
            'sign_type' => 'MD5',
        ];
        ksort($signs);
        $string = '';
        foreach ($signs as $k => $v) {
            if ($v) {
                $string .= $k . '=' . $v . '&';
            }
        }
        $string .= 'key=' . $this->key;
        $signStr = strtoupper(md5($string));
        //构建请求参数
        $param = '';
        $param .= '<xml>';
        $param .= '<appid>' . $this->app_id . '</appid>';
        $param .= '<mch_id>' . $this->mch_id . '</mch_id>';
        $param .= '<nonce_str>' . $nonce . '</nonce_str>';
        $param .= '<notify_url>' . $this->notify_url2 . '</notify_url>';
        $param .= '<out_refund_no>' . $out_refund_no . '</out_refund_no>';
        $param .= '<out_trade_no>' . $orderno . '</out_trade_no>';
        $param .= '<total_fee>' . $amount . '</total_fee>';
        $param .= '<refund_fee>' . $amount . '</refund_fee>';
        //$param .= '<transaction_id></transaction_id>';
        $param .= '<sign_type>MD5</sign_type>';
        $param .= '<sign>' . $signStr . '</sign>';
        $param .= '</xml>';
        $res = $this->db->refundWx($uid, $out_refund_no, $orderno, $amount, $param);
        if ($res['code'] < 0) {
            return array('code' => -2, 'msg' => $res['msg'], 'data' => $res);
        }
        $resWx = $this->toCurl($httpUrl, $param, 1);
        $this->db->refundModify($res['data'], $resWx);
        if ($resWx['code'] < 0) {
            return array('code' => -2, 'msg' => $resWx['msg'], 'data' => $res);
        }
        return array('code' => 0, 'msg' => 'success', 'data' => $resWx['data']);
    }

    //退款通知
    public function refundNotice()
    {
//        $xml = '<xml><return_code>SUCCESS</return_code><appid><![CDATA[wx081bb28635ee4455]]></appid><mch_id><![CDATA[1683618974]]></mch_id><nonce_str><![CDATA[2844fb3e077b085988461f9ba2160315]]></nonce_str><req_info><![CDATA[6D6csHjz4PW8JlYswpj1DVjQgkWr3RixQN+dPwz/oIjHBa95DWV2TBu1qDVz0rgAJICNjYDW0wIXvk1oWU951y8oQCYwLCTbjJ/z0jpVFgj4tWXm3uf6I2WUplRSOazIxD1HObRg0nGgmtwtTjuMBaYj9u8uqY5mj7p25n2n04wzEULPVn51XvFtvMHpQ4HNkEDwWISkf5pepMCKeDWYaZKGmiSx9WCKxbrEnQbfRC1qCc1KNroc7ij6TM75u/0vU2CqusxXkZcm0RZZc0cG2Mx3Jxan52uacLts5Qv7QxYVh4aEOa30iyVoKNliq55yG2PxxVRA8eURZbSzP3T83nz3NygXvgJ/TNMSvrJjbuqIblcUJbvrTVhWdyI9iwAa+THzx5e0WXrWnMg0qwMW9D9INKHhgr/RmmWYxtTy3YEe8RaRB7XhHqLCWWgodapJQkgr/oOqgtHAoqjVzgVstZM4ND493VTj1gdVyTzkVwrkHdqNtB/6bC1b8mVGULalih7691SCTSHXXVrWItS0p8QFQTkE2/ZuQKWNuBtqTkY5LwqkPx7sLEw97khf0YqxRUuuSGND//4A2THaKVTUYlRD5KTRNaOtfGJdB9MMAxLrraChWcGwvTzqLpng+oTDLY1ufsMTQ6Wb07tjAlV+uzzVKN+t1IrPy7fXZfNnLolKOjS5IMFwVr4IM6uNTdMLgjo2d+COqIY5VIJXSzy7bjpEvMzv8X1K9lBpVVLL3lPPfXWUu2YP003KaedUmR+R0TEmhmUgX6DruMnNoZ433K/fQ5jEihewS3VfpzVMPlUz03XW3guVpjVxYqOfNX8WgO9ebhA3zxW7Ag4toTGPe195ukEqcIIvV7HMkfhQeWqDXixgL83p8NrxBCqAbjKkP6d27IEX0tkldYiCFcnlshVr6tKhqK25Nd3I8a6RN/cjhYAW4gdGVol4kF3ugS8httMX5qh7+I+qPs26zgtfTotJAUu4UU2hXDzt5Ot75WJ17b9c3ts0PVhn3DnLfzODEIE0yUBAX2wxjpEfMuQT6mb3Xd6kck0XH4J/64alC+0vz1m4qXZ5d3q9/NWlr3/wO9j/R5yaXxI1XH+aIHUUGs6lnxOIeSDTQ1zsd5O+BvQ54rKkzeUqlhpAzz6deOAU]]></req_info></xml>';
        $this->logJson('-----------------------------------------------------------------------------------------------'); //----------------1
        $this->logJson('wx notice：'); //----------------2
        $xml = file_get_contents('php://input');
        $this->logJson($xml); //----------------3
        $lastid = $this->db->refundNotice($xml);
        $this->logJson($xml); //----------------4
        $prefix = '<![CDATA['; $suffix = ']]>';
        //return_code
        $res = preg_match('/<return_code>(.*?)<\/return_code>/', $xml, $matches);
        if (!$res) {
            return $this->toJson(-2, 'return_code 缺失');
        }
        $return_code = $matches[1];
        if (substr($return_code, 0, strlen($prefix)) == $prefix) {
            $return_code = substr($return_code, 9);
        }
        if (substr($return_code, -3) == $suffix) {
            $return_code = substr($return_code, 0, -3);
        }
        if ($return_code != 'SUCCESS') {
            return $this->toJson(-2, '通信失败');
        }
        $items['return_code'] = $return_code;
        //req_info
        $res = preg_match('/<req_info>(.*?)<\/req_info>/', $xml, $matches);
        if (!$res) {
            return $this->toJson(-2, 'req_info 缺失');
        }
        $req_info = $matches[1];
        if (substr($req_info, 0, strlen($prefix)) == $prefix) {
            $req_info = substr($req_info, 9);
        }
        if (substr($req_info, -3) == $suffix) {
            $req_info = substr($req_info, 0, -3);
        }
        $items['req_info'] = $req_info;
        $this->logJson($req_info); //----------------5
        $req_info = base64_decode($req_info);
        $key = md5($this->key);
        $req_info = openssl_decrypt($req_info, 'aes-256-ecb', $key, OPENSSL_RAW_DATA);
        $this->logJson($req_info); //----------------6
        $this->logJson(['notice_id' => $lastid, 'req_info' => $req_info]); //----------------7
        $this->db->refundNoticeModify2($lastid, $req_info);
        $this->logJson($req_info); //----------------8
        //out_trade_no
        $res = preg_match('/<out_trade_no>(.*?)<\/out_trade_no>/', $req_info, $matches);
        if (!$res) {
            return $this->toJson(-2, 'out_trade_no 缺失');
        }
        $out_trade_no = $matches[1];
        if (substr($out_trade_no, 0, strlen($prefix)) == $prefix) {
            $out_trade_no = substr($out_trade_no, 9);
        }
        if (substr($out_trade_no, -3) == $suffix) {
            $out_trade_no = substr($out_trade_no, 0, -3);
        }
        $items['out_trade_no'] = $out_trade_no;
        $this->logJson($out_trade_no); //----------------9
        $res = $this->db->refundNoticeModify($lastid, $out_trade_no);
        $this->logJson(['notice_id'=>$lastid, 'out_trade_no' => $out_trade_no, 'data' => $res]); //----------------10
        return $this->toJson(0, '', $items);
    }

    //构造JOSN
    public function logJson($d)
    {
        return true; //是否开启日志之开关
        $log = 'wxRefundNotice.json';
        $d2 = toDate() . '：';
        $d2 .= '《《《《《《《《《《《《《《《《《《《《《《《《《《';
        $d2 .= '》》》》》》》》》》》》》》》》》》》》》》》》》》：';
        $d2 .= json_encode($d, JSON_UNESCAPED_UNICODE);
        file_put_contents($log, $d2 . PHP_EOL, FILE_APPEND);
    }
}